#include "BlockCraft.h"

using namespace std;

Environment env;
Player player;

bool breakme = false;

//--------------------------------------------------------------
void BlockCraft::setup(){
    ofSetDataPathRoot("data/");
    ofBackground(186, 228, 229);
    drawScale = 40.0f;
    viewOffset.set(-30, -30);
    mousePos.set(0, 0);
    rawMousePos.set(0, 0);
    ofHideCursor();
    mouseSprite.loadImage("cursor.png");
    displayDebug = false;
    lastbutton = 0;
}

void BlockCraft::exit() {
    Resources::release();
}

//--------------------------------------------------------------
void BlockCraft::update(){
    int x = rawMousePos.x,
        y = rawMousePos.y;
    mousePos.set(x/drawScale-viewOffset.x, y/drawScale-viewOffset.y);

    player.update();
    env.update();

    viewOffset.x = (ofGetWidth() /drawScale-player.xPos()-mousePos.x)/2.0f;
    viewOffset.y = (ofGetHeight()/drawScale-player.yPos()-mousePos.y)/2.0f;
}

//--------------------------------------------------------------
void BlockCraft::draw(){
    drawBackground();
    ofPushMatrix();
    ofTranslate(0, ofGetHeight());
    ofScale(drawScale, -drawScale);
    ofTranslate(viewOffset.x, viewOffset.y);

    env.draw(drawScale, viewOffset);

    player.draw();

    ofPopMatrix();

    char buf[80];
    sprintf(buf, "BlockCraft 2D - InDev %s", BLOCKCRAFT_VERSION);
    ofSetColor(0x888888);
    ofDrawBitmapString(buf, 1, 11);
    ofSetColor(0xFFFFFF);
    ofDrawBitmapString(buf, 0, 10);

    if (displayDebug) {
        ofDrawBitmapString(player.debugPos, 0, 20);
        ofDrawBitmapString(player.debugVel, 0, 30);

        sprintf(buf, "Cur: (%i, %i) / Prv: (%i, %i)",
			player.target.block.x,      player.target.block.y,
			player.target.block_old.x, player.target.block_old.y);
        ofDrawBitmapString(string(buf), 0, 40);
        sprintf(buf, "Mouse Position: (%8f, %8f)", mousePos.x, mousePos.y);
        ofDrawBitmapString(string(buf), 0, 50);
        sprintf(buf, "Particles: %i", (int)env.particles.size());
        ofDrawBitmapString(string(buf), 0, 60);
        sprintf(buf, "Last Button: %i", lastbutton);
        ofDrawBitmapString(string(buf), 0, 70);
        sprintf(buf, "tID: %i; cID: %i", (player.target.block.x == -1 ? -1 : env.blockByCoord(player.target.block.x,player.target.block.y).ID), player.getCurrentInventoryItemID());
        ofDrawBitmapString(string(buf), 0, 80);
    }

    ofEnableAlphaBlending();
    ofSetColor(0xFFFFFF);
    player.drawInventory();
    ofDisableAlphaBlending();

    //Sleep(500);
}

//--------------------------------------------------------------
void BlockCraft::keyPressed(int key){
    switch (key) {
        case 'd':
        case 'D':
            player.move('r');
            player.keyAPressed = false;
            player.keyDPressed = true;
            break;
        case 'a':
        case 'A':
            player.move('l');
            player.keyAPressed = true;
            player.keyDPressed = false;
            break;
        case 'w':
        case 'W':
        case ' ':
            player.jump(); break;
        case '+':
        case '=':
            drawScale *= 1.25f; break;
        case '-':
            drawScale *= 0.8f; break;
        case 'q':
        case 'Q':
            player.throwItem(); break;
        case OF_KEY_F11:
            ofToggleFullscreen();
            break;
        case OF_KEY_F3:
            displayDebug = !displayDebug;
            break;
        case 'c':
            player.scrollInventory(true); break;
        case 'z':
            player.scrollInventory(false); break;
		case 'b':
			DebugBreak(); break;
    }

    if (glutGetModifiers() | GLUT_ACTIVE_SHIFT) player.sneaking = true;
    else player.sneaking = false;
    lastbutton = key;
}

//--------------------------------------------------------------
void BlockCraft::keyReleased(int key){
    switch (key) {
        case 'd':
        case 'D':
            player.keyDPressed = false;
            break;
        case 'a':
        case 'A':
            player.keyAPressed = false;
            break;
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '0':
            int slotnumber = key - '1';
            if (slotnumber == -1) slotnumber = 9;
            player.scrollInventoryTo(slotnumber);
            break;
    }
}

//--------------------------------------------------------------
void BlockCraft::mouseMoved(int x, int y){
    static float lastup = ofGetElapsedTimef();
    if (ofGetElapsedTimef() - lastup < 1/90.0f) return;
    updateMousePosition(x, y);
    lastup = ofGetElapsedTimef();
}

//--------------------------------------------------------------
void BlockCraft::mouseDragged(int x, int y, int button){
    static float lastup = ofGetElapsedTimef();
    if (ofGetElapsedTimef() - lastup < 1/90.0f) return;
    updateMousePosition(x, y);
    lastup = ofGetElapsedTimef();
}

//--------------------------------------------------------------
void BlockCraft::mousePressed(int x, int y, int button){
    if ((button == 2) && (player.target.active)) {
        //env.placeBlock(player.aimAt.x,
        //               player.aimAt.y);
		//env.placeBlock();

        char dir;
        int dirX = player.target.block.direction.x,
            dirY = player.target.block.direction.y;

        if      (dirX > 0) dir = 'E';
        else if (dirX < 0) dir = 'W';
        else if (dirY > 0) dir = 'U';
        else if (dirY < 0) dir = 'D';
        else               dir = ' ';

        env.blockByCoord(player.target.block.x, player.target.block.y)
            .activate(Block::BlockActivationEvent(&player, player.currentItem->ID, dir));
    } else if (button == 0) {
        player.startSwinging();
    }

    lastbutton = button;
}

//--------------------------------------------------------------
void BlockCraft::mouseReleased(int x, int y, int button){
    if (button == 0) {
        player.stopSwinging();
    }

    lastbutton = button;
}

//--------------------------------------------------------------
void BlockCraft::windowResized(int w, int h){
    const float BG_AR = 2.0382165605095541401273885350318;
    float ar = (float)ofGetWidth() / ofGetHeight();

    float frac;

    bgparams.txlo = 0;
    bgparams.txhi = 1,
    bgparams.tylo = 0;
    bgparams.tyhi = 1;

    if (ar > BG_AR) {
        frac = (1-BG_AR/ar)/2.0f;
        bgparams.tylo = frac;
        bgparams.tyhi = 1-frac;
    } else {
        frac = (1-ar/BG_AR)/2.0f;
        bgparams.txlo = frac;
        bgparams.txhi = 1-frac;
    }
}

void BlockCraft::updateMousePosition(int x, int y) {
    rawMousePos.set(x, ofGetHeight() - y);
}

bool BlockCraft::isInDebugMode() {
    return displayDebug;
}

void BlockCraft::drawBackground() {
    const int w = ofGetWidth(),
              h = ofGetHeight();

    glEnable(GL_TEXTURE_2D);
    ofSetColor(0xFFFFFF);
    glBindTexture(GL_TEXTURE_2D, Resources::get()->backgroundTexture());

    glBegin(GL_QUADS);
        glTexCoord2f(bgparams.txlo, bgparams.tylo);
            glVertex2i(0, 0);
        glTexCoord2f(bgparams.txhi, bgparams.tylo);
            glVertex2i(w, 0);
        glTexCoord2f(bgparams.txhi, bgparams.tyhi);
            glVertex2i(w, h);
        glTexCoord2f(bgparams.txlo, bgparams.tyhi);
            glVertex2i(0, h);
    glEnd();
}
